#include "transpo.h"

transColum *
allocTransColumns(int textSize, int keyLength)
{
	int i, aux;
	transColum * columns;
	
	if ( (columns = malloc(sizeof(transColum) * (keyLength) )) == NULL )
	   return NULL;
	
	for (i = 0; i < keyLength; i++)
	{
		aux = ( ((textSize % keyLength) / (i + 1)) != 0 )? 1:0;
		columns[i].size = textSize / keyLength + aux;
		
		if ( (columns[i].elem = malloc(sizeof(int) * (columns[i].size) )) == NULL )
			return NULL;	//no libero todo
	}
	
	return columns;
}

void
freeTransColumns(transColum * columns, int length)
{
	int i;
	
	for (i = 0; i < length; i++)
		free(columns[i].elem);
	
	free(columns);
	
	return;
}

void
solveTranspo(int *s, long size)
{
   int i, j, numCol;
   transColum * columns[MAX_KEY_LENGTH + 1];
   int charac, acum;
   int freqQ[MAX_KEY_LENGTH + 1], maxFreq, bestSol;
      
   for (numCol = MAX_KEY_LENGTH, j = 0; numCol >= MIN_KEY_LENGTH; numCol--, j++)
   {
   		if ( (columns[numCol] = allocTransColumns(size, numCol)) == NULL)
   		{
   			printf("Error en transposicion\n");
   			return;
   		}
   		
   		acum = 0;
   		for (i = 0; i < numCol; i++)
   		{
   			memcpy(columns[numCol][i].elem, &s[acum], columns[numCol][i].size * sizeof(int));
   			acum += columns[numCol][i].size;
   		}
   		
   		freqQ[numCol] = 0;

   		for (i = 0; i < size; i++)
   		{
   			charac = columns[numCol][i%numCol].elem[i/numCol];
   			
   			//chequeo si tiene el bigrama QU
   			if (charac == LETRA_Q && (i+1) < size 
   			     && columns[numCol][(i+1)%numCol].elem[(i+1)/numCol] == LETRA_U )
   			     freqQ[numCol]++;
   			
   		}
   		   	
   }
   
   	maxFreq = 0;
	for (numCol = MAX_KEY_LENGTH; numCol >= MIN_KEY_LENGTH; numCol--)
	{
//		printf("%d\n", freqQ[numCol]);
		if ( freqQ[numCol] >= maxFreq)
		{
			maxFreq = freqQ[numCol];
			bestSol = numCol;
		}
	}

	//imprimo
	printf("Opcion %d:\n", 0);
	for (i = 0; i < size; i++)
	{
		charac = columns[bestSol][i%bestSol].elem[i/bestSol];
		
		if (charac <= LETRA_N)
			printf("%c", 'A' + charac);
		else if (charac == LETRA_ENIE)
			printf("%c", 209);
		else
			printf("%c", 'A' + charac-1);
	}
	printf("\n\n");
	freeTransColumns(columns[bestSol], bestSol);
	
	for (numCol = MAX_KEY_LENGTH, j = 1; numCol >= MIN_KEY_LENGTH; numCol--, j++)
	{
		if (numCol == bestSol)
			continue;
			
   		printf("Opcion %d:\n", j);
   		for (i = 0; i < size; i++)
   		{
   			charac = columns[numCol][i%numCol].elem[i/numCol];
   			
   			if (charac <= LETRA_N)
				printf("%c", 'A' + charac);
			else if (charac == LETRA_ENIE)
				printf("%c", 209);
			else
				printf("%c", 'A' + charac-1);
   		}
   		printf("\n\n");
   		
   		freeTransColumns(columns[numCol], numCol);
	}

	return;
}

int
checkTransposition (alphabetArray cypherFreq, alphabetArray sortedLangFreq,
                  int top, float tole)
{
   int i, j, tooDifferent = 0, checked;
    
   if (tole > 100 || tole < 0 || top < 1)
      return -1;
    
   for (i = 0; i < top && !tooDifferent; i++)
   {
      checked = 0;
      for (j = 0; j < ALPHABET_NUM && !checked; j++)
      {
         if (sortedLangFreq[i].c == cypherFreq[j].c)
         {
            checked = 1;
            if (cypherFreq[j].freq / sortedLangFreq[i].freq * 100 < tole)
               tooDifferent = 1;
         }
      }
   }
    
   return !tooDifferent;
}
